package com.grao.waterschool.human.manager.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.grao.waterschool.human.common.BusinessException;
import com.grao.waterschool.human.common.R;
import com.grao.waterschool.human.entiry.dto.CourseHistoryDto;
import com.grao.waterschool.human.entiry.dto.CourseHistoryListDto;
import com.grao.waterschool.human.entiry.dto.GetCourseHistory;
import com.grao.waterschool.human.entiry.po.SchoolCourseHistory;
import com.grao.waterschool.human.entiry.po.TSysTuser;
import com.grao.waterschool.human.entiry.vo.AvgInfo;
import com.grao.waterschool.human.entiry.vo.CourseHistoryExcelVO;
import com.grao.waterschool.human.entiry.vo.CourseHistoryListVO;
import com.grao.waterschool.human.entiry.vo.CourseHistoryVO;
import com.grao.waterschool.human.manager.service.CourseHistoryListService;
import com.grao.waterschool.human.manager.service.CourseHistoryService;
import com.grao.waterschool.human.manager.service.UserService;
import com.grao.waterschool.human.mapper.SchoolCourseHistoryMapper;
import com.grao.waterschool.human.utils.MinioUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class CourseHistoryServiceImpl implements CourseHistoryService {

    @Autowired
    private SchoolCourseHistoryMapper schoolCourseHistoryMapper;

    @Autowired
    private CourseHistoryListService courseHistoryListService;

    @Autowired
    private UserService userService;

    private final Set<Integer> generatedIds = new HashSet<>();

    @Autowired
    MinioUtil minioUtil;

    private final String outputBucketName = "userimages";

    @Override
    @Transactional
    public R insertCourseHistory(CourseHistoryDto courseHistoryDto) {
        if (ObjectUtil.isEmpty(courseHistoryDto.getJgh()) || ObjectUtil.isEmpty(courseHistoryDto.getKch()) || ObjectUtil.isEmpty(courseHistoryDto.getJsh()))
            throw new BusinessException("缺少基本参数");
        if (ObjectUtil.isEmpty(courseHistoryDto.getCourseHistoryList())) throw new BusinessException("缺少统计参数");
        SchoolCourseHistory schoolCourseHistory = dtoToEntity(courseHistoryDto);
        if (ObjectUtil.isNull(schoolCourseHistory)) throw new BusinessException("entity转换错误");
        schoolCourseHistory.setType(2);
        schoolCourseHistory.setId(generateRandomId());
        schoolCourseHistoryMapper.insert(schoolCourseHistory);
        courseHistoryDto.getCourseHistoryList().forEach(courseHistoryListDto -> {
            courseHistoryListDto.setCourseHistoryId(schoolCourseHistory.getId());
        });
        courseHistoryListService.insertCourseHistoryList(courseHistoryDto.getCourseHistoryList());
        return R.success(schoolCourseHistory);
    }

    @Override
    @Transactional
    public R deleteCourseHistory(String courseHistoryId) {
        SchoolCourseHistory schoolCourseHistory = schoolCourseHistoryMapper.selectById(courseHistoryId);
        if (ObjectUtil.isNull(schoolCourseHistory)) throw new BusinessException("未查询到巡查记录");
        schoolCourseHistoryMapper.deleteById(courseHistoryId);
        courseHistoryListService.deleteCourseHistory(courseHistoryId);
        return R.success();
    }

    @Override
    public Page<SchoolCourseHistory> getCourseHistory(GetCourseHistory getCourseHistory) {
        QueryWrapper<SchoolCourseHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 1);
        if (ObjectUtil.isNotEmpty(getCourseHistory.getZC())) queryWrapper.eq("ZC", getCourseHistory.getZC());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getJSH())) queryWrapper.eq("JSH", getCourseHistory.getJSH());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getJGH())) queryWrapper.eq("JGH", getCourseHistory.getJGH());
        Page<SchoolCourseHistory> page = new Page<>(getCourseHistory.getCurrentPage(), getCourseHistory.getPageSize());
        page = schoolCourseHistoryMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Override
    public void getPicObject(String picName, HttpServletResponse response) throws Exception {
        log.info("BucketName: {}, ObjectName: {}", outputBucketName, picName);
        InputStream objectStream = minioUtil.getObject(outputBucketName, picName);
        if (objectStream == null) {
            try {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "图片文件未找到");
            } catch (IOException e) {
                log.error("发送HTTP错误响应失败", e);
            }
            return;
        }

        try (InputStream object = objectStream) {
            response.setContentType("image/jpeg");
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = object.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            log.error("图片获取失败", e);
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "图片获取失败");
            } catch (IOException ioException) {
                log.error("发送HTTP错误响应失败", ioException);
            }
        }
    }

    @Override
    public R updateCourseHistory(CourseHistoryListDto courseHistoryListDto) {
        if (ObjectUtil.isEmpty(courseHistoryListDto.getCourseHistoryId())) throw new BusinessException("ID不能为空");
        courseHistoryListService.updateCourseHistoryList(courseHistoryListDto);
        return R.success();
    }

    @Override
    public Page<SchoolCourseHistory> getCourseHistoryByType(GetCourseHistory getCourseHistory) {
        Page<SchoolCourseHistory> page = new Page<>(getCourseHistory.getCurrentPage(), getCourseHistory.getPageSize());
        QueryWrapper<SchoolCourseHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 2);
        if (ObjectUtil.isNotEmpty(getCourseHistory.getZC())) queryWrapper.eq("ZC", getCourseHistory.getZC());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getJSH())) queryWrapper.eq("JSH", getCourseHistory.getJSH());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getJGH())) queryWrapper.eq("JGH", getCourseHistory.getJGH());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getKCH())) queryWrapper.eq("KCH", getCourseHistory.getKCH());
        if (ObjectUtil.isNotEmpty(getCourseHistory.getUserId()))
            queryWrapper.eq("inspector_id", getCourseHistory.getUserId());
        page = schoolCourseHistoryMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Override
    public CourseHistoryVO getCourseHistoryById(Integer courseHistoryId) {
        SchoolCourseHistory schoolCourseHistory = schoolCourseHistoryMapper.selectById(courseHistoryId);
        if (ObjectUtil.isNull(schoolCourseHistory)) throw new BusinessException("未查询到当前数据");
        List<CourseHistoryListVO> courseHistoryListVOList = courseHistoryListService.courseHistoryList(courseHistoryId);
        CourseHistoryVO courseHistoryVO = entityToVo(schoolCourseHistory);
        courseHistoryVO.setCourseHistoryListVOList(courseHistoryListVOList);
        return courseHistoryVO;
    }

    @Override
    public List<AvgInfo> getAvgBycollege(CourseHistoryDto courseHistoryDto) {
        return courseHistoryListService.getAvgBycollege(courseHistoryDto);
    }

    @Override
    public void outPutCourseHistory(GetCourseHistory getCourseHistory, HttpServletResponse response) throws IOException {

        String username = "";
        TSysTuser user = userService.getuserById(getCourseHistory.getUserId());
        if(ObjectUtil.isNotNull(user)) username = user.getTusername();
        log.info("username:{}" + username);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        String format = simpleDateFormat.format(date);
        log.info("format:{}" + format);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");

        String fileName = username+format+".xlsx";
        String eFileName = URLEncoder.encode(fileName,StandardCharsets.UTF_8.toString());
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + eFileName);

        // 使用 EasyExcel 构建 ExcelWriter
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), CourseHistoryExcelVO.class).build()) {
            int sheetNo = 0;
            if (StpUtil.hasRole("admin")) {
                getCourseHistory.setUserId(null);
            } else {
                getCourseHistory.setUserId(StpUtil.getLoginIdAsString());
            }
            List<CourseHistoryExcelVO> courseHistoryList = schoolCourseHistoryMapper.getCourseHistory(getCourseHistory);
            log.info("courseHistory:{}", getCourseHistory);
            if (!courseHistoryList.isEmpty()) {
                // 每组数据写入一个新的 sheet
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo, "课程历史信息" + (sheetNo + 1)).build();
                excelWriter.write(courseHistoryList, writeSheet);
                sheetNo++;
            }

            // 如果没有任何数据，输出提示信息
            if (sheetNo == 0) {
                EasyExcel.write(response.getOutputStream(), CourseHistoryExcelVO.class).sheet("Sheet1").doWrite(Collections.emptyList());
                response.getOutputStream().write("没有查询到课程信息".getBytes());
            }
        }
    }

    private SchoolCourseHistory dtoToEntity(CourseHistoryDto courseHistoryDto) {
        if (ObjectUtil.isNull(courseHistoryDto)) return null;
        SchoolCourseHistory schoolCourseHistory = new SchoolCourseHistory();
        schoolCourseHistory.setInspectorId(courseHistoryDto.getInspectorId());
        schoolCourseHistory.setType(courseHistoryDto.getType());
        schoolCourseHistory.setKch(courseHistoryDto.getKch());
        schoolCourseHistory.setKcmc(courseHistoryDto.getKcmc());
        schoolCourseHistory.setJgh(courseHistoryDto.getJgh());
        schoolCourseHistory.setZc(courseHistoryDto.getZc());
        schoolCourseHistory.setZyh(courseHistoryDto.getZyh());
        schoolCourseHistory.setNj(courseHistoryDto.getNj());
        schoolCourseHistory.setBh(courseHistoryDto.getBh());
        schoolCourseHistory.setKkxnd(courseHistoryDto.getKkxnd());
        schoolCourseHistory.setKkxqm(courseHistoryDto.getKkxqm());
        schoolCourseHistory.setXqj(courseHistoryDto.getXqj());
        schoolCourseHistory.setSkjc(courseHistoryDto.getSkjc());
        schoolCourseHistory.setSkrq(courseHistoryDto.getSkrq());
        schoolCourseHistory.setSksj(courseHistoryDto.getSksj());
        schoolCourseHistory.setJxbrs(courseHistoryDto.getJxbrs());
        schoolCourseHistory.setSkdd(courseHistoryDto.getSkdd());
        schoolCourseHistory.setJsh(courseHistoryDto.getJsh());
        return schoolCourseHistory;
    }

    private CourseHistoryVO entityToVo(SchoolCourseHistory schoolCourseHistory) {
        if (ObjectUtil.isNull(schoolCourseHistory)) return null;
        CourseHistoryVO courseHistoryVO = new CourseHistoryVO();
        courseHistoryVO.setInspectorId(schoolCourseHistory.getInspectorId());
        courseHistoryVO.setType(schoolCourseHistory.getType());
        courseHistoryVO.setKch(schoolCourseHistory.getKch());
        courseHistoryVO.setKcmc(schoolCourseHistory.getKcmc());
        courseHistoryVO.setJgh(schoolCourseHistory.getJgh());
        courseHistoryVO.setZc(schoolCourseHistory.getZc());
        courseHistoryVO.setZyh(schoolCourseHistory.getZyh());
        courseHistoryVO.setNj(schoolCourseHistory.getNj());
        courseHistoryVO.setBh(schoolCourseHistory.getBh());
        courseHistoryVO.setXqj(schoolCourseHistory.getXqj());
        courseHistoryVO.setSkjc(schoolCourseHistory.getSkjc());
        courseHistoryVO.setSkrq(schoolCourseHistory.getSkrq());
        courseHistoryVO.setSksj(schoolCourseHistory.getSksj());
        courseHistoryVO.setJxbrs(schoolCourseHistory.getJxbrs());
        courseHistoryVO.setSkdd(schoolCourseHistory.getSkdd());
        courseHistoryVO.setJsh(schoolCourseHistory.getJsh());
        return courseHistoryVO;
    }

    private Integer generateRandomId() {
        int id;
        do {
            id = (int) (Math.random() * 900000000) + 100000000;
        } while (generatedIds.contains(id));
        generatedIds.add(id);
        return id;
    }
}
